use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use crate::crypto::{CryptoService, CryptoError};

pub const GOD_PEER_ID: &str = "GOD_PEER_V1_OFFICIAL_MATH_NETWORK";
pub const GOD_PUBLIC_KEY: &str = "god_public_key_secure_hash_1234567890";

#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub enum PeerRole {
    God,
    Trusted,
    Regular,
}

#[derive(Serialize, Deserialize, Clone)]
pub struct TrustCertificate {
    pub peer_id: String,
    pub public_key: String,
    pub role: PeerRole,
    pub trust_level: u8,
    pub parent_peer_id: String,
    pub issued_by: String,
    pub issue_date: u64,
    pub expiry_date: u64,
    pub signature: String,
    pub max_subordinates: u8,
    pub current_subordinates: u8,
    pub is_active: bool,
}

#[derive(Serialize, Deserialize)]
struct SignableCertificate {
    pub peer_id: String,
    pub public_key: String,
    pub role: PeerRole,
    pub trust_level: u8,
    pub parent_peer_id: String,
    pub issued_by: String,
    pub issue_date: u64,
    pub expiry_date: u64,
    pub max_subordinates: u8,
    pub current_subordinates: u8,
    pub is_active: bool,
}

pub struct TrustTree {
    certificates: HashMap<String, TrustCertificate>,
    children_map: HashMap<String, Vec<String>>,
    max_depth: u8,
    max_children_per_node: u8,
}

impl TrustTree {
    pub fn new(max_depth: u8, max_children: u8) -> Self {
        let mut certificates = HashMap::new();
        let mut children_map = HashMap::new();

        let god_certificate = TrustCertificate {
            peer_id: GOD_PEER_ID.to_string(),
            public_key: GOD_PUBLIC_KEY.to_string(),
            role: PeerRole::God,
            trust_level: 0,
            parent_peer_id: GOD_PEER_ID.to_string(),
            issued_by: GOD_PEER_ID.to_string(),
            issue_date: 1_700_000_000,
            expiry_date: u64::MAX,
            signature: "BUILT_IN_GOD_PEER_SIGNATURE".to_string(),
            max_subordinates: max_children,
            current_subordinates: 0,
            is_active: true,
        };

        certificates.insert(GOD_PEER_ID.to_string(), god_certificate);
        children_map.insert(GOD_PEER_ID.to_string(), Vec::new());

        Self {
            certificates,
            children_map,
            max_depth,
            max_children_per_node: max_children,
        }
    }

    pub fn authorize_subordinate_signed(
        &mut self,
        crypto_service: &CryptoService,
        issuer_peer_id: String,
        applicant_peer_id: String,
        applicant_public_key: String,
    ) -> Result<TrustCertificate, CryptoError> {
        let issuer_cert = self.certificates.get(&issuer_peer_id)
            .ok_or(CryptoError("Issuer not found".to_string()))?;

        if !issuer_cert.is_active {
            return Err(CryptoError("Issuer certificate is not active".to_string()));
        }

        if issuer_cert.trust_level >= self.max_depth {
            return Err(CryptoError("Cannot authorize subordinates at maximum depth".to_string()));
        }

        if issuer_cert.current_subordinates >= issuer_cert.max_subordinates {
            return Err(CryptoError("Issuer has reached maximum subordinate limit".to_string()));
        }

        let mut new_certificate = TrustCertificate {
            peer_id: applicant_peer_id.clone(),
            public_key: applicant_public_key,
            role: PeerRole::Trusted,
            trust_level: issuer_cert.trust_level + 1,
            parent_peer_id: issuer_peer_id.clone(),
            issued_by: issuer_peer_id.clone(),
            issue_date: current_timestamp(),
            expiry_date: current_timestamp() + 180 * 24 * 60 * 60,
            signature: "".to_string(),
            max_subordinates: self.max_children_per_node,
            current_subordinates: 0,
            is_active: true,
        };

        // 生成签名
        let signature = self.sign_certificate(crypto_service, &new_certificate)?;
        new_certificate.signature = signature;

        // 更新数据结构
        self.certificates.insert(applicant_peer_id.clone(), new_certificate.clone());
        
        self.children_map.entry(issuer_peer_id.clone())
            .or_insert_with(Vec::new)
            .push(applicant_peer_id.clone());
        self.children_map.insert(applicant_peer_id.clone(), Vec::new());

        if let Some(issuer_cert) = self.certificates.get_mut(&issuer_peer_id) {
            issuer_cert.current_subordinates += 1;
        }

        Ok(new_certificate)
    }

    fn sign_certificate(
        &self,
        crypto_service: &CryptoService,
        certificate: &TrustCertificate,
    ) -> Result<String, CryptoError> {
        let signable_data = self.prepare_signable_data(certificate);
        crypto_service.sign_data(&certificate.issued_by, &signable_data)
    }

    fn prepare_signable_data(&self, certificate: &TrustCertificate) -> Vec<u8> {
        let signable_cert = SignableCertificate {
            peer_id: certificate.peer_id.clone(),
            public_key: certificate.public_key.clone(),
            role: certificate.role.clone(),
            trust_level: certificate.trust_level,
            parent_peer_id: certificate.parent_peer_id.clone(),
            issued_by: certificate.issued_by.clone(),
            issue_date: certificate.issue_date,
            expiry_date: certificate.expiry_date,
            max_subordinates: certificate.max_subordinates,
            current_subordinates: certificate.current_subordinates,
            is_active: certificate.is_active,
        };

        serde_json::to_vec(&signable_cert)
            .expect("Failed to serialize certificate for signing")
    }

    pub fn verify_certificate_signature(
        &self,
        crypto_service: &CryptoService,
        certificate: &TrustCertificate,
        issuer_public_key: &str,
    ) -> Result<bool, CryptoError> {
        let signable_data = self.prepare_signable_data(certificate);
        crypto_service.verify_signature(issuer_public_key, &signable_data, &certificate.signature)
    }

    pub fn is_god_peer(&self, peer_id: &str) -> bool {
        peer_id == GOD_PEER_ID
    }

    pub fn get_certificate(&self, peer_id: &str) -> Option<&TrustCertificate> {
        self.certificates.get(peer_id)
    }

    pub fn validate_issuer_chain(&self, peer_id: &str) -> bool {
        let mut current_id = peer_id;
        let mut visited = HashSet::new();

        while let Some(cert) = self.certificates.get(current_id) {
            if visited.contains(current_id) {
                return false;
            }
            visited.insert(current_id);

            if self.is_god_peer(current_id) {
                return true;
            }

            current_id = &cert.parent_peer_id;
        }

        false
    }
}

pub fn current_timestamp() -> u64 {
    use std::time::{SystemTime, UNIX_EPOCH};
    SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()
}